package baiqitun.stupro.subject.service.impl;

import baiqitun.stupro.common.exception.enums.support.StuproExceptionEnum;
import baiqitun.stupro.common.exception.enums.support.ExistedExceptionEnum;
import baiqitun.stupro.common.exception.enums.support.NotFoundExceptionEnum;
import baiqitun.stupro.common.exception.support.ExistedException;
import baiqitun.stupro.common.service.support.MyServiceImpl;
import baiqitun.stupro.common.workflow.enums.ProcessDefinitionKeyEnum;
import baiqitun.stupro.common.exception.support.NotFoundException;
import baiqitun.stupro.common.exception.StuproException;
import baiqitun.stupro.common.workflow.util.TaskUtil;
import baiqitun.stupro.security.entity.SysDepart;
import baiqitun.stupro.security.entity.SysDepartUser;
import baiqitun.stupro.security.entity.SysUser;
import baiqitun.stupro.security.service.SysDepartService;
import baiqitun.stupro.security.service.SysDepartUserService;
import baiqitun.stupro.security.service.SysUserService;
import baiqitun.stupro.subject.entity.SysSubject;
import baiqitun.stupro.subject.entity.SysTutorInfo;
import baiqitun.stupro.subject.mapper.SysTutorInfoMapper;
import baiqitun.stupro.subject.service.SysSubjectService;
import baiqitun.stupro.subject.service.SysTutorInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotBlank;
import java.util.List;

/**
 * <p>
 * 导师信息表 服务实现类
 * </p>
 *
 * @author kedaji
 * @since 2020-04-01
 */
@Service
public class SysTutorInfoServiceImpl extends MyServiceImpl<SysTutorInfoMapper, SysTutorInfo> implements SysTutorInfoService {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysDepartService sysDepartService;
    @Autowired
    private SysSubjectService sysSubjectService;
    @Autowired
    private SysDepartUserService sysDepartUserService;
    @Autowired
    private TaskUtil taskUtil;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean save(@Validated() SysTutorInfo tutorInfo){
        return super.save(tutorInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveTutorToRootDepart(SysUser user, SysTutorInfo tutorInfo,
                                         @NotBlank(message = "部门id不能为空") String departId) {
        SysDepart rootDepart = sysDepartService.getExistedEntity(departId, new NotFoundException(NotFoundExceptionEnum.DEPART_NOT_FOUND));
        if (StringUtils.isNotBlank(rootDepart.getParentId())){
            throw new StuproException(StuproExceptionEnum.ILLEGAL_OPERATION);
        }
        SysSubject defaultSubject = sysSubjectService.getDefaultSubjectByRootDepart(departId);
        if (defaultSubject == null){
            throw new StuproException(StuproExceptionEnum.UNKNOWN).put(SysDepart.class, "id", departId).put(SysSubject.class,"subject", null);
        }
        // 保存用户与部门的关系
        sysDepartUserService.saveUserToDepart(user, departId);
        // 保存导师与方向的关系
        tutorInfo.setUserId(user.getId());
        this.save(tutorInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void moveTutorToOtherSubject(String userId, String subjectId, String updateBy) {
        sysUserService.checkExisted(userId, new ExistedException(ExistedExceptionEnum.PROJECT_USER_RELATION_EXISTED));
        sysSubjectService.checkExisted(subjectId, new ExistedException(ExistedExceptionEnum.PROJECT_USER_RELATION_EXISTED));
        // 查找当前导师所在系
        SysDepartUser queryDepartUser = new SysDepartUser();
        queryDepartUser.setUserId(userId);
        SysDepartUser relation = sysDepartUserService.getOne(new QueryWrapper<>(queryDepartUser));
        // 检查当前导师所在系与所选科目是否是同一个系
        SysSubject defaultSubject = sysSubjectService.getDefaultSubjectByRootDepart(relation.getDepartId());
        if (! defaultSubject.getDepartId().equals(relation.getDepartId())){
            throw new StuproException(StuproExceptionEnum.ILLEGAL_OPERATION);
        }
        SysTutorInfo tutorInfo = new SysTutorInfo();
        tutorInfo.setSubjectId(subjectId).setId(getTutorInfoByUserId(userId).getId());
        updateById(tutorInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void handleTaskForSelectTutor(String taskId, String result) {
        taskUtil.checkExisted(ProcessDefinitionKeyEnum.SELECT_TUTOR.name(), taskId);
        taskUtil.handleTask(ProcessDefinitionKeyEnum.SELECT_TUTOR.name(), taskId, result);
    }

    @Override
    public void handleTaskForCancelSelectedTutor(String taskId, String result) {
        taskUtil.checkExisted(ProcessDefinitionKeyEnum.CANCEL_SELECTED_TUTOR.name(), taskId);
        taskUtil.handleTask(ProcessDefinitionKeyEnum.CANCEL_SELECTED_TUTOR.name(), taskId, result);
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public List<Task> listTaskForSelectTutorRequest(String tutorUserId) {
        return taskUtil.listTaskByAssignee(ProcessDefinitionKeyEnum.SELECT_TUTOR.name(), tutorUserId);
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public List<Task> listTaskForCancelSelectedTutorRequest(String tutorUserId) {
        return taskUtil.listTaskByAssignee(ProcessDefinitionKeyEnum.CANCEL_SELECTED_TUTOR.name(), tutorUserId);
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public SysTutorInfo getTutorInfoByUserId(String userId) {
        SysTutorInfo queryTutorInfo = new SysTutorInfo();
        queryTutorInfo.setUserId(userId);
        return getOne(new QueryWrapper<>(queryTutorInfo));
    }
}
